let inSqlUtil = require("./inSqlUtil");
let result = {};

let sqlConnection = {};
let syncSqlConnection = {};

result.map = {};

/**
 * 初始化
 */
result.init = (connection1, connection2) => {
    sqlConnection = connection1;
    syncSqlConnection = connection2;
    inSqlUtil.init(sqlConnection, syncSqlConnection);
}

/**
 * 处理单条数据
 */
result.handleOne = (data) => {
    // 如果是t_开头，则说明是为了防止和mysql关键字冲突，需要去掉t_，所有下划线改为驼峰
    let obj = {};
    for (let key in data) {
        let newKey = key;
        if (newKey.startsWith("t_")) {
            newKey = newKey.substring(2);
        }
        let newKeyArr = newKey.split("_");
        for (let j = 1; j < newKeyArr.length; j++) {
            newKeyArr[j] = newKeyArr[j].charAt(0).toUpperCase() + newKeyArr[j].substring(1);
        }
        newKey = newKeyArr.join("");
        obj[newKey] = data[key];
    }
    return obj;
}

/**
 * 处理查询到的数据
 */
result.handleList = (data) => {
    // 如果是t_开头，则说明是为了防止和mysql关键字冲突，需要去掉t_，所有下划线改为驼峰
    let res = [];
    for (let i = 0; i < data.length; i++) {
        let obj = result.handleOne(data[i]);
        res.push(obj);
    }
    return res;
}

/**
 * 添加数据
 * @param tableName 表名
 * @param entity 实体
 * @returns {*}
 */
result.insert = (tableName, entity) => {
    // 获取entity的key
    let keys = Object.keys(entity);
    // 获取entity的value
    let values = Object.values(entity);
    // 拼接sql
    let sql = `insert into ${tableName}(${keys.join(",")}) values(${values.map(item => `?`).join(",")})`;
    return sqlConnection.query(sql, values);
}

/**
 * 更新数据
 */
result.update = (tableName, entity, where) => {
    // 获取entity的key
    let keys = Object.keys(entity);
    // 获取entity的value
    let values = Object.values(entity);
    // 拼接sql
    let sql = `update ${tableName} set ${keys.map((item) => `${item} = ?`).join(",")} where ${where}`;
    return syncSqlConnection.query(sql, values);
}

/**
 * 删除数据
 */
result.delete = (tableNameInput, entity) => {
    // 将表名转换为下划线
    let tableName = inSqlUtil.nameToUnderline(tableNameInput);

    // 获取entity的key
    let keys = Object.keys(entity);
    // 获取entity的value
    let values = Object.values(entity);
    // 拼接sql
    let sql = `delete from ${tableName} where ${keys.map((item) => `${item} = ?`).join(" and ")}`;
    return syncSqlConnection.query(sql, values);
}


/**
 * 查询数据
 * 操作符：
 *      等于 eq
 *      like查询 like
 *      模糊查询 vague
 *      大于 gt
 *      小于 lt
 *      大于等于 ge
 *      小于等于 le
 *      开区间查询 openInterval
 *      闭区间查询 close
 */
let selectAf = (tableNameInput, entityParam, fieldsOfSelectedInput) => {
    // 将表名转换为下划线
    let tableName = inSqlUtil.nameToUnderline(tableNameInput);
    let fieldsOfSelected = inSqlUtil.getFieldsStr(tableName, fieldsOfSelectedInput);

    // 获取entity的key
    let keys = Object.keys(entityParam);
    // 如果为空则查询所有
    if (keys.length === 0) {
        return syncSqlConnection.query(`select ${fieldsOfSelected} from ${tableName}`);
    }

    // 根据:分割key，如果有:则表示是特殊查询，如果没有则表示eq查询
    for (let i = 0; i < keys.length; i++) {
        let key = keys[i];
        let keyArr = key.split(":");
        let fieldsName = inSqlUtil.getField(tableName, keyArr[0]);
        if (keyArr.length === 1) {
            keys[i] = `${fieldsName} = ?`;
        } else {
            switch (keyArr[1]) {
                case "eq":
                    keys[i] = `${fieldsName} = ?`;
                    break;
                case "like":
                    keys[i] = `${fieldsName} like ?`;
                    break;
                case "vague":
                    keys[i] = `${fieldsName} like CONCAT('%',?,'%')`;
                    break;
                case "gt":
                    keys[i] = `${fieldsName} > ?`;
                    break;
                case "lt":
                    keys[i] = `${fieldsName} < ?`;
                    break;
                case "ge":
                    keys[i] = `${fieldsName} >= ?`;
                    break;
                case "le":
                    keys[i] = `${fieldsName} <= ?`;
                    break;
                case "openInterval":
                    keys[i] = `${fieldsName} > ? and ${fieldsName} < ?`;
                    break;
                case "closeInterval":
                    keys[i] = `${fieldsName} >= ? and ${fieldsName} <= ?`;
                    break;
            }
        }
    }
    // 获取entity的value
    let values = Object.values(entityParam);
    let valuesLast = [];
    for (let i = 0; i < values.length; i++) {
        if (keys[i].includes("Interval")) {
            valuesLast.push(values[i][0]);
            valuesLast.push(values[i][1]);
        } else {
            valuesLast.push(values[i]);
        }
    }


    // 拼接sql
    let sql = `select ${fieldsOfSelected} from ${tableName} where ${keys.join(" and ")}`;
    let res = syncSqlConnection.query(sql, valuesLast);
    inSqlUtil.check(tableName, fieldsOfSelected, res);
    return res;
}

result.select = (tableName, entityParam, fieldsOfSelected) => {
    return result.handleList(selectAf(tableName, entityParam, fieldsOfSelected));
}

result.selectOne = (tableName, entityParam, fieldsOfSelected) => {
    let res = selectAf(tableName, entityParam, fieldsOfSelected);
    if (res.length === 0) {
        return null;
    }
    return result.handleOne(res[0]);
}

result.idMap = {};

result.selectById = (tableName, id, fieldsOfSelected) => {
    let idMap = result.idMap;
    // 将table名转换为下划线
    tableName = tableName.replace(/([A-Z])/g, "_$1").toLowerCase();

    // 如果map中有数据，且不超过2分钟，则直接取map中的数据
    if (idMap[tableName] && new Date().getTime() - idMap[tableName].time < 1200000) {
        let res = selectAf(tableName, {[idMap[tableName].id]: id}, fieldsOfSelected);
        if (res.length === 0) {
            return null;
        }
        return result.handleOne(res[0]);
    }

    // 查询该table的id字段
    let fieldOfId = syncSqlConnection.query(`select COLUMN_NAME from information_schema.COLUMNS where table_name = '${tableName}' and COLUMN_KEY = 'PRI'`);
    let idField = fieldOfId[0].COLUMN_NAME;
    console.log("idField", idField);
    idMap[tableName] = {time: new Date().getTime(), "id": idField};

    let res = selectAf(tableName, {[idField]: id}, fieldsOfSelected);
    if (res.length === 0) {
        return null;
    }
    return result.handleOne(res[0]);
}


module.exports = result;